package binary_tree

import (
	"fmt"
	"strings"
)


// PrintTree: 打印二叉树   ------------------------------------
func  PrintTree(node *TreeNode) {
	if node == nil {
		return
	}
	fmt.Println("------------------------------------    打印二叉树    ------------------------------------")
	InProcess(node, 0, 0)
}

// nodeType: 0: 根节点  1:左节点 2:右节点
func InProcess(node *TreeNode, level int, nodeType int) {
	if node == nil {
		return
	}
	InProcess(node.Right, level+1, 2)
	nodeStr := FormatterFactory.CreateFormatter(FormatterFactory{}, node, nodeType).Format()
	fmt.Println(strings.Repeat("    ", level), nodeStr)
	InProcess(node.Left, level+1, 1)
}

type Formatter interface {
	Format() string
}

type FormatterFactory struct {}

func (f FormatterFactory) CreateFormatter(node *TreeNode, nodeType int) Formatter {
	switch nodeType {
	case 0:
		return &RootNodeFormatter{Node: node}
	case 1:
		return &LeftNodeFormatter{Node: node}
	case 2:
		return &RightNodeFormatter{Node: node}
	}
	return nil
}

type RootNodeFormatter struct {
	Node *TreeNode
}

func (R *RootNodeFormatter) Format() string {
	return "<" + R.Node.Value + ">"
}

type LeftNodeFormatter struct {
	Node *TreeNode
}

func (l *LeftNodeFormatter) Format() string {
	return "⬆" + l.Node.Value + "⬆"
}

type RightNodeFormatter struct {
	Node *TreeNode
}

func (r *RightNodeFormatter) Format() string {
	return "⬇" + r.Node.Value + "⬇"
}

// PrintTree: 打印多叉树   ------------------------------------
func  PrintMultiForkTree(node *MultiForkTreeNode) {
	if node == nil {
		return
	}
	fmt.Println("------------------------------------    打印多叉树    ------------------------------------")
	PrintMultiForkTreePosProcess(node, 0)
}

func PrintMultiForkTreePosProcess(node *MultiForkTreeNode, nodeLevel int) {
	if node == nil {
		return
	}
	for _, child := range node.Children {
		PrintMultiForkTreePosProcess(child, nodeLevel+1)
	}
	fmt.Println(formatNodeValueStr(node, nodeLevel))
}

func formatNodeValueStr(node *MultiForkTreeNode, nodeLevel int) string {
	return  strings.Repeat("    ", nodeLevel) + "⬇" +node.Value
}